﻿#define _CRT_SECURE_NO_WARNINGS

#include <iostream>
#include <vector>
using namespace std;

struct Point
{
	int _x;
	int _y;
};

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{
		cout << "Date(int year, int month, int day)" << endl;
	}

	Date(const Date& d)
		:_year(d._year)
		, _month(d._month)
		, _day(d._day)
	{
		cout << "Date(const Date& d)" << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

//int main()
//{
//	// C++98⽀持的
//	int a1[] = { 1, 2, 3, 4, 5 };
//	int a2[5] = { 0 };
//	Point p = { 1, 2 };
//
//	// C++11⽀持的
//	int x = { 1 };
//	int x1{ 3 };
//
//	Date d = { 2025, 1, 1 }; // 没有调用拷贝构造
//	Date d1{ 2025, 1, 2 }; // 没有调用拷贝构造
//	// 这⾥d2引⽤的是{ 2024, 10, 31 }构造的临时对象
//	const Date& d2 = { 2024, 10, 31 }; // 没有调用拷贝构造
//
//	// 需要注意的是C++98⽀持单参数时类型转换，也可以不⽤{}
//	Date d3 = { 2025 }; // 没有调用拷贝构造
//	Date d4 = 2025; // 没有调用拷贝构造
//
//	vector<Date> s;
//	// ⽐起有名对象和匿名对象传参，这⾥{}更有性价⽐
//	s.push_back(Date{ 2025, 1, 1 });
//
//	Date d5 = { 2025, 3, 3 };
//	vector<int> f = { 1,2,3,4,5,6,7,8,9,0 };
//
//	return 0;
//}


void test_lvalues() 
{
	// 变量
	int a = 10;                    // a是左值

	// 数组元素
	int arr[5];
	arr[0] = 1;                    // arr[0]是左值

	// 类对象成员
	struct Point { int x, y; };
	Point p;
	p.x = 10;                      // p.x是左值

	// 解引用
	int* ptr = &a;
	*ptr = 20;                     // *ptr是左值

	// 字符串字面量（特殊情况）
	const char* str = "hello";     // "hello"是左值
	// &"hello";                   // ✓ 可以取地址
}

int getValue() { return 100; }
void test_rvalues() 
{
	// 字面量
	int a = 42; // 42是右值
	double b = 3.14; // 3.14是右值
	bool flag = true; // true是右值

	// 算术表达式
	int x = 10, y = 20;
	int sum = x + y; // (x + y)是右值

	// 函数返回值（非引用）
	int val = getValue(); // getValue()是右值

	// 临时对象
	std::string s = std::string("temp");  // std::string("temp")是右值
	std::vector<int> v = std::vector<int>{ 1,2,3 }; // 临时vector是右值
}
//int main()
//{
//	int x = 5;
//
//	// const左值引用可以引用右值
//	const int& cr1 = 10;
//	const int& cr2 = x + 5;
//
//	int y = 10;
//
//	// 没有move时：右值引用不能绑定左值
//	// int&& r1 = y;
//
//	// 使用move后：将左值转为右值引用
//	int&& r2 = move(y);
//	cout << "y = " << y << endl;
//	cout << "r2 = " << r2 << endl;
//	r2 = 20;
//	cout << "y = " << y << endl;
//
//	return 0;
//}

void process(int& val) { cout << "lvalue\n"; }
void process(int&& val) { cout << "rvalue\n"; }

//int main()
//{
//	int&& rr1 = 10;  // rr1本身是左值！
//
//	// 验证：
//	int* p = &rr1;           // ✓ 可以取地址 - 证明rr1是左值
//	// int* p2 = &10;        // ❌ 不能取字面量的地址
//
//	// 函数重载测试
//	process(rr1);            // 输出: lvalue (不是rvalue!)
//	process(10);             // 输出: rvalue
//
//	return 0;
//}

//int main()
//{
//	int i = 0;
//	int& r1 = i;
//	int& r2 = r1;
//
//	int&& rr1 = 10;
//	// 无法将左值绑定到右值引用
//	//int&& rr2 = rr1;
//
//	return 0;
//}

void f(int& x)
{
	cout << "左值引用重载 f(" << x << ")\n";
}
void f(const int& x)
{
	cout << "到 const 的左值引用重载 f(" << x << ")\n";
}
void f(int&& x)
{
	cout << "右值引用重载 f(" << x << ")\n";
}

//int main()
//{
//	int i = 1;
//	const int ci = 2;
//	f(i); // 调⽤ f(int&)
//	f(ci); // 调⽤ f(const int&)
//	f(3); // 调⽤ f(int&&)，如果没有 f(int&&) 重载则会调⽤ f(const int&)
//	f(std::move(i)); // 调⽤ f(int&&)
//
//	return 0;
//}


namespace STR
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		iterator begin()
		{
			return _str;
		}
		iterator end()
		{
			return _str + _size;
		}
		const_iterator begin() const
		{
			return _str;
		}
		const_iterator end() const
		{
			return _str + _size;
		}
		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			cout << "string(char* str)-构造" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}
		void swap(string& s)
		{
			std::swap(_str, s._str);
			std::swap(_size, s._size);
			std::swap(_capacity, s._capacity);
		}
		
		string(const string& s)
		{
			cout << "string(const string& s) -- 拷贝构造" << endl;
			_str = new char[s._capacity + 1];
			memcpy(_str, s._str, s._size + 1);
			_size = s._size;
			_capacity = s._capacity;
		}

		// 移动构造
		string(string&& s)
		{
			cout << "string(const string&& s) -- 移动构造" << endl;
			swap(s);
		}

		string& operator=(const string& s)
		{
			cout << "string& operator=(const string& s) -- 拷贝赋值" << endl;
			if (this != &s)
			{
				_str[0] = '\0';
				_size = 0;
				reserve(s._capacity);
				for (auto ch : s)
				{
					push_back(ch);
				}
			}
			return *this;
		}

		// 移动赋值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动赋值" << endl;
			swap(s);
			return *this;
		}

		~string()
		{
			//cout << "~string() -- 析构" << endl;
			delete[] _str;
			_str = nullptr;
		}
		char& operator[](size_t pos)
		{
			return _str[pos];
		}

		void reserve(size_t n)
		{
			cout << "_capacity:" << _capacity << endl;
			if (n > _capacity)
			{
				char* str = new char[n + 1];
				memcpy(str, _str, _size + 1);
				delete[] _str;
				_str = str;
				_capacity = n;
			}
		}
		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				int newcapacity = _capacity == 0 ? 4 : 2 * _capacity;
				reserve(newcapacity);
			}
			_str[_size] = ch;
			_size++;
			_str[_size] = '\0';
		}

		private:
			char* _str = nullptr;
			size_t _size = 0;
			size_t _capacity = 0;
	};
}


//int main()
//{
//	STR::string s1("xxxxx");
//	// 拷⻉构造
//	STR::string s2 = s1;
//	// 构造 + 拷贝构造，编译器优化为直接构造
//	STR::string s3 = STR::string("yyyyy");
//	STR::string s4 = move(s1);
//
//	return 0;
//}

//int main()
//{
//	STR::string s1("xxxxx");
//	// 拷⻉构造
//	STR::string s2 = s1;
//	// 构造+移动构造，优化后直接构造
//	STR::string s3 = STR::string("yyyyy");
//	// 移动构造
//	STR::string s4 = move(s1); 
//
//	return 0;
//}

//int main()
//{
//	STR::string s5("yyyyyyyyyyyyyyyyy");
//	STR::string s3 = s5;
//	s5 = STR::string("yyyyy");
//
//	return 0;
//}

//int main()
//{
//	typedef int& lref;
//	using rref = int&&; // 和上面等价
//
//	int n = 0;
//	lref& r1 = n; // r1 的类型是 int&
//	lref&& r2 = n; // r2 的类型是 int&
//	rref& r3 = n; // r3 的类型是 int&
//	rref&& r4 = 1; // r4 的类型是 int&&
//
//	return 0;
//}

// 由于引⽤折叠限定，f1实例化以后总是⼀个左值引⽤
template<class T>
void f1(T& x)
{ }


//int main()
//{
//	int n = 1;
//
//	// 没有折叠->实例化为void f1(int& x)
//	f1<int>(n);
//	//f1<int>(0); // 左值引用，报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	//f1<int&>(0); // 左值引用，报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&&>(n);
//	//f1<int&&>(0); // 左值引用，报错
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&>(n);
//	f1<const int&>(0); // 可接收右值
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&&>(n);
//	f1<const int&&>(0); // 可接收右值
//
//	return 0;
//}

// 由于引⽤折叠限定，f2实例化后可以是左值引⽤，也可以是右值引⽤
template<class T>
void f2(T&& x)
{ }

//int main()
//{
//	int n = 1;
//	// 没有折叠->实例化为void f2(int&& x)
//	//f2<int>(n); // 右值引用，报错
//	f2<int>(0);
//	// 折叠->实例化为void f2(int& x)
//	f2<int&>(n);
//	//f2<int&>(0); // 左值引用，报错
//	// 折叠->实例化为void f2(int&& x)
//	//f2<int&&>(n); // 右值引用，报错
//	f2<int&&>(0);
//
//	return 0;
//}

template<class T>
void Function(T&& t)
{
	int a = 0;
	T x = a;

	cout << "&a = " << &a << endl;
	cout << "&x = " << &x << endl << endl;
}

//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值
//
//	return 0;
//}

//int main()
//{
//	int a = 1;
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值
//
//	return 0;
//}

template<class T>
class func
{
	// ...
	// 万能引用
	template<class Y>
	void Function(Y&& t)
	{
		int a = 0;
		Y x = a;

		cout << "&a = " << &a << endl;
		cout << "&x = " << &x << endl << endl;
	}
	// ...
};

int main()
{
	//const int b = 9;
	//// a是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int&t)
	//Function(b);


	return 0;
}